//------------------------------------------------------------------------------
#include <QtGui>
#include <QMessageBox>
#include <QDate>
#include <QDesktopServices>
#include <QSqlRecord>
#include "CFindFrm.h"
#include "CBLsFrm.h"
#include "CTextEditDelegate.h"
#include "CPrintFrm.h"
#include "CSelectArticleFrm.h"
#include "CSelectTypeBLFrm.h"
#include "version.h"
#include "CComboResultFrm.h"
#include "CMySQL.h"
#include "CHelp.h"
//------------------------------------------------------------------------------
CBLsFrm::CBLsFrm(QString name, QString lastCode, QWidget *parent) : CMyMainWindow(name, parent) {
	setActionCur(CGlobal::acConstruct);
	
	setupUi(this);

	setStatusBar(NULL);
	
	actLock->setChecked(true);
	
	masterTable="teteBLs";
	primaryKey="code";
	curCode="0";
	document->addItem("Bon de livraison", QVariant("L"));
	document->addItem("Bon de retour", QVariant("R"));
	
	tabWidget->removeTab(0);
	createGrille();
	
	loadSchema();
	
	loadPrintPopupMenu(toolBar);
	
	if(CMySQL::getInstance()->getNbEnregistrement(masterTable) == 0) {
		setActionCur(CGlobal::acTableVide);
	}else
	{
		if(!chargeDonnees(lastCode, CGlobal::seNone)) {
			chargeDonnees("", CGlobal::sePremier);
		}
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::setNumero(int numero) {
	chargeDonnees(QString::number(numero), CGlobal::seNone);	
}
//------------------------------------------------------------------------------
void CBLsFrm::setActionCur(CGlobal::EAction action) {
	actionCur=action;
	
	switch(actionCur) {
		case CGlobal::acNone:
			actPremiereFiche->setEnabled(true);
			actFichePrecedente->setEnabled(true);
			actFicheSuivante->setEnabled(true);
			actDerniereFiche->setEnabled(true);
			
			actAjouter->setEnabled(true);
			actSupprimer->setEnabled(true);
			
			actValider->setEnabled(false);
			actAnnuler->setEnabled(false);
			
			actRechercheUneFiche->setEnabled(true);
			enableBtnPrint(true);
			
			enableChamps(true);
			tabWidget->setEnabled(true);
			document->setEnabled(false);
			avertModifClientShown=false;
			break;
		case CGlobal::acTableVide:
			actPremiereFiche->setEnabled(false);
			actFichePrecedente->setEnabled(false);
			actFicheSuivante->setEnabled(false);
			actDerniereFiche->setEnabled(false);
			
			actAjouter->setEnabled(true);
			actSupprimer->setEnabled(false);
			
			actValider->setEnabled(false);
			actAnnuler->setEnabled(false);
			
			actRechercheUneFiche->setEnabled(false);
			enableBtnPrint(false);
			
			clearChamps();
			enableChamps(false);
		
			code->setValue("");
			creation->setValue("");
			devis->setValue("");
			devis->setData(QVariant());
			commande->setValue("");
			commande->setData(QVariant());
			
			tabWidget->setEnabled(false);
			lignesWidget->setRowCount(0);
			document->setEnabled(false);
			break;
		case CGlobal::acAjout:
		case CGlobal::acAjoutFromDevis:
		case CGlobal::acAjoutFromCommande:
			clearChamps();
			initChamps();
			enableChamps(true);
			document->setEnabled(true);
			
			code->setText("");
			codeClient->setFocus();
			lignesWidget->setRowCount(0);
			document->setCurrentIndex(0);
		case CGlobal::acModif:
			actPremiereFiche->setEnabled(false);
			actFichePrecedente->setEnabled(false);
			actFicheSuivante->setEnabled(false);
			actDerniereFiche->setEnabled(false);
			
			actAjouter->setEnabled(false);
			actSupprimer->setEnabled(false);
			
			actValider->setEnabled(true);
			actAnnuler->setEnabled(true);
			
			actRechercheUneFiche->setEnabled(false);
			enableBtnPrint(false);
			
			tabWidget->setEnabled(false);
			break;
		case CGlobal::acAfficheLigne:
		default:
			break;
	}
}
//------------------------------------------------------------------------------
CGlobal::EAction CBLsFrm::getActionCur(void) {
	return actionCur;
}
//------------------------------------------------------------------------------
void CBLsFrm::closeEvent(QCloseEvent * event) {
	if(getActionCur() != CGlobal::acNone && getActionCur() != CGlobal::acTableVide) {
		QMessageBox msgBox(	QMessageBox::Warning, tr("Attention"), 
							tr("Veuillez annuler ou valider avant de sortir"), QMessageBox::Ok);
		msgBox.exec();	
		
		event->ignore();
	}else {
		emit quit(objectName(), curCode);
		event->accept();
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::createGrille(void) {
	CTextEditDelegate *delegate=new CTextEditDelegate();
	QList<CColumnModel *> *columnModel=new QList<CColumnModel *>();
	
	columnModel->append(new CColumnModelInt(cnbLigne, "numeroLigne", tr("Ligne"), Qt::AlignRight, NULL, Qt::ItemIsEnabled));
	columnModel->append(new CColumnModelString(cnbArticle, "article", tr("Article"), Qt::AlignLeft, 
			new QIcon(":coMexpert/images/camera.png"), Qt::ItemIsEnabled));
	columnModel->append(new CColumnModelString(cnbDescArticle, "descriptionArticle", tr("Description")));
	columnModel->append(new CColumnModelDouble(cnbQuantite, "quantite", tr("Qté.")));
	columnModel->append(new CColumnModelString(cnbUnite, "unite", tr("Unité"), Qt::AlignLeft, 
			new QIcon(":coMexpert/images/attach.png"), Qt::ItemIsEnabled));
	columnModel->append(new CColumnModelDouble(cnbPrix, "prixUnitaireHT", tr("Prix")));
	columnModel->append(new CColumnModelDouble(cnbTotal, "", tr("Total"), Qt::AlignRight, NULL, Qt::ItemIsEnabled));
	columnModel->append(new CColumnModelDouble(cnbTva, "taux", tr("Taux de TVA"), Qt::AlignRight, NULL, Qt::ItemIsEnabled));
	
	lignesWidget=new CGrilleWidget(columnModel, this, true, true);
	connect(lignesWidget, SIGNAL(ajoute(bool&)), this, SLOT(ajouteLigne(bool&)));
	connect(lignesWidget, SIGNAL(supprime(int, bool&)), this, SLOT(supprimeLigne(int, bool&)));
	connect(lignesWidget, SIGNAL(monte(int)), this, SLOT(monteLigne(int)));
	connect(lignesWidget, SIGNAL(descend(int)), this, SLOT(descendLigne(int)));
	connect(lignesWidget, SIGNAL(cellChanged(int, int)), this, SLOT(modifiLigne(int, int)));
	connect(lignesWidget, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(ligneDoubleClicked(int, int)));
	tabWidget->addTab(lignesWidget, tr("Lignes"));
	
	lignesWidget->setColumnWidth(cnbDescArticle, 250);
	
	lignesWidget->setItemDelegateForColumn(cnbDescArticle, delegate);
}
//------------------------------------------------------------------------------
void CBLsFrm::loadInfoClient(QString client) {
	QSqlQuery *query;
	QString requete;
		
	requete="SELECT nom, adresse1, adresse2, adresse3, codePostal, ville, pays, ";
	requete+="modeReglement, conditionReglement ";
	requete+="FROM client WHERE code = \""+client+"\" ";
		
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		if(query->next()) {
			QSqlRecord rec=query->record();
			
			nomClient->setValue(rec.value("nom"));
			
			adresseFacturation1->setValue(rec.value("adresse1"));
			adresseFacturation2->setValue(rec.value("adresse2"));
			adresseFacturation3->setValue(rec.value("adresse3"));
			codePostalFacturation->setValue(rec.value("codePostal"));
			villeFacturation->setValue(rec.value("ville"));
			paysFacturation->setValue(rec.value("pays"));
			
			nomLivraison->setValue(rec.value("nom"));
			adresseLivraison1->setValue(rec.value("adresse1"));
			adresseLivraison2->setValue(rec.value("adresse2"));
			adresseLivraison3->setValue(rec.value("adresse3"));
			codePostalLivraison->setValue(rec.value("codePostal"));
			villeLivraison->setValue(rec.value("ville"));
			paysLivraison->setValue(rec.value("pays"));
			
			modeReglement->setValue(rec.value("modeReglement"));
			conditionReglement->setValue(rec.value("conditionReglement"));
		}else {
			nomClient->setValue("");
			
			adresseFacturation1->setValue("");
			adresseFacturation2->setValue("");
			adresseFacturation3->setValue("");
			codePostalFacturation->setValue("");
			villeFacturation->setValue("");
			paysFacturation->setValue("");
			
			nomLivraison->setValue("");
			adresseLivraison1->setValue("");
			adresseLivraison2->setValue("");
			adresseLivraison3->setValue("");
			codePostalLivraison->setValue("");
			villeLivraison->setValue("");
			paysLivraison->setValue("");
			
			modeReglement->setValue("");
			conditionReglement->setValue("");
		}
	}
	
	delete query;
}
//------------------------------------------------------------------------------
void CBLsFrm::loadInfoAdresse(int numeroAdresse, bool facturation) {
	QSqlQuery *query;
	QString requete;
		
	requete="SELECT nom, adresse1, adresse2, adresse3, codePostal, ville, pays ";
	requete+="FROM adressesClient WHERE client = \""+codeClient->getValue()+"\" AND numero = "+QString::number(numeroAdresse);
		
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		if(query->next()) {
			QSqlRecord rec=query->record();
			
			if(facturation) {
				nomClient->setValue(rec.value("nom"));
			
				adresseFacturation1->setValue(rec.value("adresse1"));
				adresseFacturation2->setValue(rec.value("adresse2"));
				adresseFacturation3->setValue(rec.value("adresse3"));
				codePostalFacturation->setValue(rec.value("codePostal"));
				villeFacturation->setValue(rec.value("ville"));
				paysFacturation->setValue(rec.value("pays"));
			}else {
				nomLivraison->setValue(rec.value("nom"));
				adresseLivraison1->setValue(rec.value("adresse1"));
				adresseLivraison2->setValue(rec.value("adresse2"));
				adresseLivraison3->setValue(rec.value("adresse3"));
				codePostalLivraison->setValue(rec.value("codePostal"));
				villeLivraison->setValue(rec.value("ville"));
				paysLivraison->setValue(rec.value("pays"));
			}
		}else {
			if(facturation) {
				nomClient->setValue("");
			
				adresseFacturation1->setValue("");
				adresseFacturation2->setValue("");
				adresseFacturation3->setValue("");
				codePostalFacturation->setValue("");
				villeFacturation->setValue("");
				paysFacturation->setValue("");
			}else {
				nomLivraison->setValue("");
				adresseLivraison1->setValue("");
				adresseLivraison2->setValue("");
				adresseLivraison3->setValue("");
				codePostalLivraison->setValue("");
				villeLivraison->setValue("");
				paysLivraison->setValue("");
			}
		}
	}
	
	delete query;
}
//------------------------------------------------------------------------------
void CBLsFrm::loadGrille(void) {
	CGlobal::EAction oldAction=getActionCur();
	QString requete;
	QSqlQuery *query;
	
	setActionCur(CGlobal::acAfficheLigne);
	
	requete="SELECT lb.numeroLigne, lb.article, lb.descriptionArticle, lb.quantite, lb.unite, ";
	requete+="lb.prixUnitaireHT, lb.quantite*lb.prixUnitaireHT, tauxTva*100 AS taux, 0 ";
	requete+="FROM ligneBLs AS lb ";
	requete+="WHERE lb.bl="+curCode+" ";
	requete+="ORDER BY lb.numeroLigne";
	
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		lignesWidget->loadGrille(query);
	}
	
	delete query;
	
	calculMontant();
	
	setActionCur(oldAction);
}
//------------------------------------------------------------------------------
void CBLsFrm::calculMontant(int ignoreRow) {
	int y;
	double mnt=0;
	double mntTTc=0;
	
	for(y=0;y<lignesWidget->rowCount();y++) {
		if(y != ignoreRow) {
			double mntL=lignesWidget->item(y, cnbTotal)->text().toDouble();
			mnt+=mntL;
			mntTTc+=mntL*(1+lignesWidget->item(y, cnbTva)->text().toDouble()/100);
		}
	}
	
	montant->setText(QString("%1").arg(mnt, 0, 'f', 2));
	TTC->setText(QString("%1").arg(mntTTc, 0, 'f', 2));
}
//------------------------------------------------------------------------------
void CBLsFrm::calculTotalLigne(int row) {
	double total=lignesWidget->item(row, cnbQuantite)->text().toDouble()*lignesWidget->item(row, cnbPrix)->text().toDouble();
	
	lignesWidget->item(row, cnbTotal)->setText(QString("%1").arg(total, 0, 'f', 2));
}
//------------------------------------------------------------------------------
bool CBLsFrm::loadEnteteFromDevis(int numDevis) {
	QString requete;
	QSqlQuery *query;
	
 	requete="SELECT codeClient, nomClient, adresse1, adresse2, adresse3, codePostal, ville, pays, ";
	requete+="modeReglement, conditionReglement, nomDevis ";
	requete+="FROM teteDevis WHERE code = "+QString::number(numDevis);
	
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		if(query->next()) {	
			QSqlRecord rec=query->record();
			
			if(rec.value("codeClient") == "") {
				QMessageBox msgBox(QMessageBox::Warning, tr("Erreur"), tr("Ce devis n'a pas été établie à un client"), QMessageBox::Ok);
				msgBox.exec();
				return false;
			}
			
			codeClient->setValue(rec.value("codeClient"));
			nomClient->setValue(rec.value("nomClient"));
			
			adresseFacturation1->setValue(rec.value("adresse1"));
			adresseFacturation2->setValue(rec.value("adresse2"));
			adresseFacturation3->setValue(rec.value("adresse3"));
			codePostalFacturation->setValue(rec.value("codePostal"));
			villeFacturation->setValue(rec.value("ville"));
			paysFacturation->setValue(rec.value("pays"));
			
			nomLivraison->setValue(rec.value("nomClient"));
			adresseLivraison1->setValue(rec.value("adresse1"));
			adresseLivraison2->setValue(rec.value("adresse2"));
			adresseLivraison3->setValue(rec.value("adresse3"));
			codePostalLivraison->setValue(rec.value("codePostal"));
			villeLivraison->setValue(rec.value("ville"));
			paysLivraison->setValue(rec.value("pays"));
			
			modeReglement->setValue(rec.value("modeReglement"));
			conditionReglement->setValue(rec.value("conditionReglement"));
			
			devis->setValue(rec.value("nomDevis"));
			devis->setData(numDevis);
			commande->setValue("");
			commande->setData(QVariant());
		}
	}
	
	delete query;
	return true;
}
//------------------------------------------------------------------------------
void CBLsFrm::loadEnteteFromCommande(int numeroCommande) {
	QString requete;
	QSqlQuery *query;
	
	requete="SELECT tc.codeClient, tc.nomClient, tc.adresseFacturation1, tc.adresseFacturation2, ";
	requete+="tc.adresseFacturation3, tc.codePostalFacturation, tc.villeFacturation, tc.paysFacturation, ";
	requete+="tc.adresseLivraison1, tc.adresseLivraison2, ";
	requete+="tc.adresseLivraison3, tc.codePostalLivraison, tc.villeLivraison, tc.paysLivraison, ";
	requete+="tc.modeReglement, tc.conditionReglement, tc.devis, tc.nomCommande, td.nomDevis ";
	requete+="FROM teteCommandes AS tc ";
	requete+="LEFT JOIN teteDevis AS td ON td.code=tc.devis ";
	requete+="WHERE tc.code = "+QString::number(numeroCommande);
	
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		if(query->next()) {
			QSqlRecord rec=query->record();
			
			codeClient->setValue(rec.value("codeClient"));
			nomClient->setValue(rec.value("nomClient"));
			nomLivraison->setValue(rec.value("nomClient"));
			
			adresseFacturation1->setValue(rec.value("adresseFacturation1"));
			adresseFacturation2->setValue(rec.value("adresseFacturation2"));
			adresseFacturation3->setValue(rec.value("adresseFacturation3"));
			codePostalFacturation->setValue(rec.value("codePostalFacturation"));
			villeFacturation->setValue(rec.value("villeFacturation"));
			paysFacturation->setValue(rec.value("paysFacturation"));
			
			adresseLivraison1->setValue(rec.value("adresseLivraison1"));
			adresseLivraison2->setValue(rec.value("adresseLivraison2"));
			adresseLivraison3->setValue(rec.value("adresseLivraison3"));
			codePostalLivraison->setValue(rec.value("codePostalLivraison"));
			villeLivraison->setValue(rec.value("villeLivraison"));
			paysLivraison->setValue(rec.value("paysLivraison"));
			
			modeReglement->setValue(rec.value("modeReglement"));
			conditionReglement->setValue(rec.value("conditionReglement"));
			
			devis->setValue(rec.value("nomDevis"));
			devis->setData(rec.value("devis"));
			
			commande->setValue(rec.value("nomCommande"));
			commande->setData(numeroCommande);
		}
	}
	
	delete query;
}
//------------------------------------------------------------------------------
void CBLsFrm::loadLigneFromDevis(int numDevis) {
	QString requete="INSERT INTO ligneBLs ";
	requete+="(bl, article, descriptionArticle, quantite, prixUnitaireHT, unite, tauxTva, nomTva) ";
	requete+="SELECT "+curCode+", ld.article, ld.descriptionArticle, ld.quantite, ld.prixUnitaireHT, ";
	requete+="ld.unite, tvc.taux, tvc.nom ";
	requete+="FROM ligneDevis AS ld ";
	requete+="INNER JOIN teteBLs AS tb ON tb.code="+curCode+" ";
	requete+="INNER JOIN article AS a ON a.code=ld.article ";
	requete+="INNER JOIN tvaClient AS tvc ON tvc.codeClient = tb.codeClient AND tvc.idTva=a.idTva  ";
	requete+="WHERE ld.devis = "+QString::number(numDevis);
			
	if(CMySQL::getInstance()->execQuery(requete)) {
		requete="UPDATE teteDevis SET status=\"ABO\" WHERE code="+QString::number(numDevis);
		CMySQL::getInstance()->execQuery(requete);
		
		loadGrille();
	}
}
//------------------------------------------------------------------------------*
void CBLsFrm::loadLigneFromCommande(int numeroCommande) {
	QSqlQuery *query;
	QString requete="INSERT INTO ligneBLs ";
	requete+="(bl, article, descriptionArticle, quantite, prixUnitaireHT, unite, tauxTva, nomTva) ";
	requete+="SELECT "+curCode+", lc.article, lc.descriptionArticle, lc.quantite, lc.prixUnitaireHT, ";
	requete+="lc.unite, tvc.taux, tvc.nom ";
	requete+="FROM ligneCommandes AS lc ";
	requete+="INNER JOIN teteBLs AS tb ON tb.code="+curCode+" ";
	requete+="INNER JOIN article AS a ON a.code=lc.article ";
	requete+="INNER JOIN tvaClient AS tvc ON tvc.codeClient = tb.codeClient AND tvc.idTva=a.idTva  ";
	requete+="WHERE lc.commande = "+QString::number(numeroCommande)+" ";
			
	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		loadGrille();
	}
	
	delete query;
}
//------------------------------------------------------------------------------
void CBLsFrm::mouvementDeStock(QString article, int ligne, double ancienneValeur, double nouvelleValeur) {
	QString requete;
	double mouvement=nouvelleValeur-ancienneValeur;
	int sens=document->itemData(document->currentIndex()).toString() == "L" ? -1 : 1;
	
	mouvement*=sens;
	
	if(mouvement != 0 && article != "") {
		requete="INSERT INTO mouvementStock (article, dateMouvement, qui, stockAvant, mouvement, bl, numeroLigneBl) ";
		requete+="SELECT code, CURDATE(), \""+CGlobal::getCurrentUser()+"\", stock, "+QString::number(mouvement)+", "+curCode+", ";
		requete+=QString::number(ligne)+" ";
		requete+="FROM article WHERE code = \""+article+"\" AND gereStock = 1 ";
				
		CMySQL::getInstance()->execQuery(requete);
				
		requete="UPDATE article SET stock=stock+("+QString::number(mouvement)+") ";
		requete+="WHERE code = \""+article+"\" AND gereStock = 1 ";
		
		CMySQL::getInstance()->execQuery(requete);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::swapRows(int n1, int n2) {
	QString requete="UPDATE ligneBLs SET numeroLigne=-"+QString().number(n1)+" WHERE bl="+curCode+" AND numeroLigne="+QString().number(n1);
	CMySQL::getInstance()->execQuery(requete);
	
	requete="UPDATE ligneBLs SET numeroLigne="+QString().number(n1)+" WHERE bl="+curCode+" AND numeroLigne="+QString().number(n2);
	CMySQL::getInstance()->execQuery(requete);
	
	requete="UPDATE ligneBLs SET numeroLigne="+QString().number(n2)+" WHERE bl="+curCode+" AND numeroLigne=-"+QString().number(n1);
	CMySQL::getInstance()->execQuery(requete);
}
//------------------------------------------------------------------------------
void CBLsFrm::showFormulaire(QSqlQuery *query, CGlobal::EAction& action) {
	QSqlRecord rec=query->record();
	
	curCode=rec.value("code").toString();
		
	code->setValue(curCode);
	nomBL->setValue(rec.value("nomBL"));
	codeClient->setValue(rec.value("codeClient"));
	nomClient->setValue(rec.value("nomClient"));
	nomClient2->setValue(!actLock->isChecked() ? rec.value("nomClient") : "");
		
	adresseFacturation1->setValue(rec.value("adresseFacturation1"));
	adresseFacturation2->setValue(rec.value("adresseFacturation2"));
	adresseFacturation3->setValue(rec.value("adresseFacturation3"));
	codePostalFacturation->setValue(rec.value("codePostalFacturation"));
	villeFacturation->setValue(rec.value("villeFacturation"));
	paysFacturation->setValue(rec.value("paysFacturation"));
		
	adresseLivraison1->setValue(rec.value("adresseLivraison1"));
	adresseLivraison2->setValue(rec.value("adresseLivraison2"));
	adresseLivraison3->setValue(rec.value("adresseLivraison3"));
	codePostalLivraison->setValue(rec.value("codePostalLivraison"));
	villeLivraison->setValue(rec.value("villeLivraison"));
	paysLivraison->setValue(rec.value("paysLivraison"));
		
	modeReglement->setValue(rec.value("modeReglement"));
	conditionReglement->setValue(rec.value("conditionReglement"));
	creation->setValue(rec.value("creation"));
	devis->setValue(rec.value("nomDevis"));
	devis->setData(rec.value("devis"));
	commande->setValue(rec.value("nomCommande"));
	commande->setData(rec.value("commande"));
	document->setCurrentIndex(document->findData(rec.value("document")));
	nomLivraison->setValue(rec.value("nomLivraison"));
	
	pretAFacture->setValue(rec.value("pretAFacture"));
	factureSepare->setValue(rec.value("factureSepare"));
	
	loadGrille();
}
//------------------------------------------------------------------------------
void CBLsFrm::showChampsAuto(void) {
	QString requete="SELECT nomBL FROM "+masterTable+" WHERE "+primaryKey+" = "+curCode;
	QSqlQuery *query;

	if(CMySQL::getInstance()->execQuery(requete, &query)) {
		if(query->next()) {
			QSqlRecord rec=query->record();
			
			nomBL->setValue(rec.value("nomBL"));
		}
	}
	
	delete query;
}
//------------------------------------------------------------------------------
void CBLsFrm::makeRequete(QString &requete, QString &alias) {
	requete="SELECT tb.*, IFNULL(td.nomDevis, '') AS nomDevis, IFNULL(tc.nomCommande, '') AS nomCommande ";
	requete+="FROM "+masterTable+" AS tb ";
	requete+="LEFT JOIN teteDevis AS td ON td.code=tb.devis ";
	requete+="LEFT JOIN teteCommandes AS tc ON tc.code=tb.commande";
	
	alias="tb";
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actAjouter_triggered(void) {	
	CSelectTypeBLFrm *selectTypeBLFrm=new CSelectTypeBLFrm(this);
	
	selectTypeBLFrm->exec();
	
	if(selectTypeBLFrm->result() == QDialog::Accepted) {
		if(selectTypeBLFrm->isDevisSelected()){
			int numDevis=selectTypeBLFrm->getInfoDevis().value("teteDevis.code").toInt();
			
			setActionCur(CGlobal::acAjoutFromDevis);
			loadEnteteFromDevis(numDevis);
		}else {
			if(selectTypeBLFrm->isCommandeSelected()) {
				int numCommande=selectTypeBLFrm->getInfoCommande().value("teteCommandes.code").toInt();
				
				setActionCur(CGlobal::acAjoutFromCommande);
				loadEnteteFromCommande(numCommande);
			}else {
				setActionCur(CGlobal::acAjout);
			}
		}
		
		creation->setValue(CMySQL::getInstance()->getCurrentDate());
		montant->setText("0.00");
		TTC->setText("0.00");
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actValider_triggered(void) {
	QString requete;
	QString condition;
	QString dateBl;
	QVariant lastCode;
	
	calculChamps(getActionCur());
	
	if(!validChamps()) return;
	if(!validLiaison()) return;
	
	if(document->currentIndex() == -1) {
		QMessageBox msgBox(	QMessageBox::Warning, tr("Attention"), 
							tr("Le type de document est obligatoire ?"), QMessageBox::Ok);
		msgBox.exec();
		
		return;
	}
	
	if(!QDate::fromString(creation->getValue(), "dd/MM/yyyy").isValid()) {
		QMessageBox msgBox(QMessageBox::Warning, tr("Erreur"), tr("Date incorrect"), QMessageBox::Ok);
		msgBox.exec();
		
		return;	
	}
	
	dateBl=QDate::fromString(creation->getValue(), "dd/MM/yyyy").toString("yyyy-MM-dd");
	
	switch(getActionCur()) {
		case CGlobal::acAjout:
		case CGlobal::acAjoutFromDevis:
		case CGlobal::acAjoutFromCommande:
			requete="INSERT INTO "+masterTable+" SET ";
			requete+="createur='"+CGlobal::getCurrentUser()+"', ";
			requete+="document='"+document->itemData(document->currentIndex()).toString()+"', ";
			if(devis->getData().isValid() && devis->getData().toInt() != 0) {
				requete+="devis = "+devis->getData().toString()+", ";
			}
			if(commande->getData().isValid() && commande->getData().toInt() != 0) {
				requete+="commande = "+commande->getData().toString()+", ";
			}
			condition="";
			break;
		case CGlobal::acModif:
			requete="UPDATE "+masterTable+" SET ";
			requete+="modification=CURDATE(), modificateur=\""+CGlobal::getCurrentUser()+"\", ";
			condition="WHERE "+primaryKey+"=\""+code->getValue()+"\"";
			break;
		default:
			return;
	}
	
	requete+="codeClient = \""+codeClient->getValue()+"\", nomClient = \""+nomClient->getValue()+"\", ";
	requete+="adresseFacturation1 = \""+adresseFacturation1->getValue()+"\", ";
	requete+="adresseFacturation2 = \""+adresseFacturation2->getValue()+"\", ";
	requete+="adresseFacturation3 = \""+adresseFacturation3->getValue()+"\", ";
	requete+="codePostalFacturation = \""+codePostalFacturation->getValue()+"\", ";
	requete+="villeFacturation = \""+villeFacturation->getValue()+"\", ";
	requete+="paysFacturation = \""+paysFacturation->getValue()+"\", ";
	requete+="adresseLivraison1 = \""+adresseLivraison1->getValue()+"\", ";
	requete+="adresseLivraison2 = \""+adresseLivraison2->getValue()+"\", ";
	requete+="adresseLivraison3 = \""+adresseLivraison3->getValue()+"\", ";
	requete+="codePostalLivraison = \""+codePostalLivraison->getValue()+"\", ";
	requete+="villeLivraison = \""+villeLivraison->getValue()+"\", ";
	requete+="paysLivraison = \""+paysLivraison->getValue()+"\", ";
	requete+="modeReglement = \""+modeReglement->getValue()+"\", ";
	requete+="conditionReglement = \""+conditionReglement->getValue()+"\", ";
	requete+="nomLivraison = \""+nomLivraison->getValue()+"\", pretAFacture = \""+pretAFacture->getValue()+"\", ";
	requete+="factureSepare = \""+factureSepare->getValue()+"\", ";
	requete+="creation = \""+dateBl+"\" ";
	
	requete+=condition;
	
	if(CMySQL::getInstance()->execQuery(requete, true, &lastCode) == 0) {
		return;
	}
	
	switch(getActionCur()) {
		case CGlobal::acAjoutFromDevis:
			setActionCur(CGlobal::acNone);
			curCode=lastCode.toString();
			loadLigneFromDevis(devis->getData().toInt());
			code->setValue(curCode);
			showChampsAuto();
			break;
		case CGlobal::acAjoutFromCommande:
			setActionCur(CGlobal::acNone);
			curCode=lastCode.toString();
			loadLigneFromCommande(commande->getData().toInt());
			code->setValue(curCode);
			showChampsAuto();
			break;
		case CGlobal::acAjout:
			setActionCur(CGlobal::acNone);
			curCode=lastCode.toString();
			code->setValue(curCode);
			showChampsAuto();
			break;
		default:
			setActionCur(CGlobal::acNone);
			curCode=code->getValue();
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actAnnuler_triggered(void) {
	
	QMessageBox msgBox(	QMessageBox::Question, tr("Confirmation"), 
						tr("Etes vous sûre de vouloir annuler ?"), QMessageBox::Yes | QMessageBox::No);
	msgBox.exec();
	
	if(msgBox.result() == QMessageBox::Yes) {
		if(!chargeDonnees(curCode, CGlobal::seNone)) {
			if(!chargeDonnees(curCode, CGlobal::sePrecedent)) {
				if(!chargeDonnees(curCode, CGlobal::seSuivant)) {
					setActionCur(CGlobal::acTableVide);
				}
			}
		}
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actSupprimer_triggered(void) {
	QMessageBox msgBox(	QMessageBox::Question, tr("Confirmation"), 
						tr("Etes vous sûre de vouloir supprimer la fiche courante ?"), QMessageBox::Yes | QMessageBox::No);
	msgBox.exec();
	
	if(msgBox.result() == QMessageBox::Yes) {
		QString requete;
		
		requete="INSERT INTO mouvementStock (article, dateMouvement, qui, stockAvant, mouvement, bl, numeroLigneBl) ";
		requete+="SELECT article, CURDATE(), \""+CGlobal::getCurrentUser()+"\", stock, IF(document=\"L\", 1, -1)*quantite, bl, ";
		requete+="numeroLigne ";
		requete+="FROM ligneBLs INNER JOIN article ON article=article.code ";
		requete+="INNER JOIN teteBLs ON bl=teteBLs.code ";
		requete+="WHERE bl = "+curCode+" AND gereStock = 1 ";
		CMySQL::getInstance()->execQuery(requete);
		
		requete="UPDATE article, ligneBLs, teteBLs SET ";
		requete+="stock=stock+IF(document=\"L\", 1, -1)*quantite ";
		requete+="WHERE article.code=article AND teteBLs.code=bl AND gereStock=1 AND bl="+curCode;
		CMySQL::getInstance()->execQuery(requete);
				
		requete="DELETE FROM "+masterTable+" WHERE "+primaryKey+"=\""+curCode+"\"";
		CMySQL::getInstance()->execQuery(requete);
		
		if(!chargeDonnees(curCode, CGlobal::sePrecedent)) {
			if(!chargeDonnees(curCode, CGlobal::seSuivant)) {
				setActionCur(CGlobal::acTableVide);
			}
		}
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::onChange(void) {
	if(getActionCur() == CGlobal::acNone) {
		setActionCur(CGlobal::acModif);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::onChangeClient(void) {
	if(getActionCur() == CGlobal::acNone || getActionCur() == CGlobal::acModif) {
		if(!avertModifClientShown) {
			QMessageBox msgBox(	QMessageBox::Question, tr("Confirmation"), 
								tr("Etes vous sûre de modifier le client du bl ?"), QMessageBox::Yes | QMessageBox::No);
								
			msgBox.exec();
			
			if(msgBox.result() == QMessageBox::No) {
				QSqlQuery *query;
				QString requete="SELECT codeClient FROM teteBLs WHERE code="+curCode;
				
				if(CMySQL::getInstance()->execQuery(requete, &query)) {
					if(query->next()) {
						QSqlRecord rec=query->record();
						
						codeClient->setValue(rec.value("codeClient"));
					}
				}
				
				delete query;
			}else {
				avertModifClientShown=true;
				setActionCur(CGlobal::acModif);
			}
		}else {
			setActionCur(CGlobal::acModif);
		}
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::onCombo(CMyComboBox *comboBox) {
	CComboResultFrm *comboResultFrm=new CComboResultFrm(comboBox->getTableRemp(), comboBox->getChampRemp(), this);
	
	comboResultFrm->setModal(true);
	comboResultFrm->exec();
	
	if(comboResultFrm->result() == QDialog::Accepted) {
		comboBox->setValue(comboResultFrm->getResult());
	}
	
	delete comboResultFrm;
}
//------------------------------------------------------------------------------
void CBLsFrm::onComboClient(CMyComboBox *comboBox) {
	CComboResultFrm *comboResultFrm=new CComboResultFrm(comboBox->getTableRemp(), comboBox->getChampRemp(), this);
	
	comboResultFrm->setModal(true);
	comboResultFrm->exec();
	
	if(comboResultFrm->result() == QDialog::Accepted) {
		comboBox->setValue(comboResultFrm->getResult());
		
		loadInfoClient(comboResultFrm->getResult());
		onChange();
	}
	
	delete comboResultFrm;
}
//------------------------------------------------------------------------------
void CBLsFrm::onClientEditingFinished(void)
{
	QString client=codeClient->getValue();
	
	if(client != "") {
		loadInfoClient(client);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actRechercheUneFiche_triggered(void) {
	CFindFrm *findFrm=new CFindFrm(masterTable, this);
	
	findFrm->setModal(true);
	findFrm->exec();
	if(findFrm->result() == QDialog::Accepted) {
		chargeDonnees(findFrm->getResult(), CGlobal::seNone);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::ajouteLigne(bool &goToLast) {
	CSelectArticleFrm *selectArticleFrm=new CSelectArticleFrm(this);
	
	if(selectArticleFrm->exec()) {
		QString requete;
		QString article=selectArticleFrm->getArticle();
		
		requete="INSERT INTO ligneBLs (bl, article, descriptionArticle, quantite, prixUnitaireHT, unite, tauxTva, nomTva) ";
		requete+="SELECT "+curCode+", \""+article+"\", a.nom, 1, ";
		requete+="IF(pac.prix IS NOT NULL, pac.prix, a.prixUnitaireHT), a.unite, tc.taux, tc.nom ";
		requete+="FROM article AS a ";
		requete+="INNER JOIN tvaClient AS tc ON tc.codeClient=\""+codeClient->getValue()+"\" AND tc.idTva=a.idTva ";
		requete+="LEFT JOIN prixArticleClient AS pac ON a.code=pac.article AND pac.client = \""+codeClient->getValue()+"\" ";
		requete+="WHERE a.code = \""+article+"\" ";
		requete+="ORDER BY pac.numero DESC LIMIT 1 ";
		
		CMySQL::getInstance()->execQuery(requete);
		
		setActionCur(CGlobal::acNone);
		
		loadGrille();
	}
	delete selectArticleFrm;
}
//------------------------------------------------------------------------------
void CBLsFrm::supprimeLigne(int row, bool& ok) {
	QTableWidgetItem *item=lignesWidget->item(row, 0);
	int numeroLigne;
	
	if(item != NULL) {
		numeroLigne=item->text().toInt();
		
		QMessageBox msgBox(	QMessageBox::Question, tr("Confirmation"), 
							tr("Etes vous sûre de vouloir supprimer la ligne numero ")+
							QString().number(numeroLigne)+tr(" ?"), QMessageBox::Yes | QMessageBox::No);
		msgBox.exec();
		
		if(msgBox.result() == QMessageBox::Yes) {
			QString requete;
			
			mouvementDeStock(lignesWidget->item(row, cnbArticle)->text(), 
							 lignesWidget->item(row, cnbLigne)->text().toInt(), 
							lignesWidget->item(row, cnbQuantite)->text().toDouble(), 0); 
			
			requete="DELETE from ligneBLs WHERE bl = "+curCode+" AND numeroLigne = "+QString().number(numeroLigne);
			
			CMySQL::getInstance()->execQuery(requete);
			
			ok=true;
		}
		
		calculMontant(row);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::modifiLigne(int row, int column) {
	QString text;
	QString requete;
	QTableWidgetItem *item;
	
	if(getActionCur() != CGlobal::acNone) return;
	item=lignesWidget->item(row, column);
	
	if(column != cnbLigne && column != cnbTotal && column != cnbTva) {
		QString text=lignesWidget->getColumnModel(column)->format(item->text());
		QString textSQL=lignesWidget->getColumnModel(column)->formatToSQL(CGlobal::addSlashesQuot(item->text()));
		QString oldTextSQL="";
		QSqlQuery *query;
		QString nomChamp=lignesWidget->getColumnModel(column)->getNomChamp();
		int numeroLigne=lignesWidget->item(row, cnbLigne)->text().toInt();
		
		requete="SELECT "+nomChamp+" FROM ligneBLs ";
		requete+="WHERE bl="+curCode+" AND numeroLigne="+QString::number(numeroLigne);
			
		if(CMySQL::getInstance()->execQuery(requete, &query)) {
			if(query->next()) {
				oldTextSQL=query->record().value(nomChamp).toString();
			}
			
			if(oldTextSQL != textSQL) {
				if(column == cnbQuantite) {
					double ancienneQuantite=oldTextSQL.toDouble();
					
					mouvementDeStock(lignesWidget->item(row, cnbArticle)->text(), 
									lignesWidget->item(row, cnbLigne)->text().toInt(),
											ancienneQuantite, text.toDouble()); 
				}
					
				requete="UPDATE ligneBLs ";
				requete+="SET "+nomChamp+" = "+textSQL+" ";
				requete+="WHERE bl="+curCode+" AND numeroLigne="+QString::number(numeroLigne);
				
				CMySQL::getInstance()->execQuery(requete);
				
				item->setText(text);
				
				calculTotalLigne(row);
				calculMontant();
		
				lignesWidget->resizeRowToContents(row);
			}
		}
		
		delete query;
	}
	
	code->setText(code->text().toUpper());
	calculChamps(getActionCur());
}
//------------------------------------------------------------------------------
void CBLsFrm::monteLigne(int row) {
	if(row > 0) {
		bool tableSwap[]={false, true, true, true, true, true, true};
		
		lignesWidget->swapRows(row, row-1, tableSwap);
		
		int curLigne=lignesWidget->item(row, cnbLigne)->text().toInt();
		int ligneSwap=lignesWidget->item(row-1, cnbLigne)->text().toInt();
		
		swapRows(curLigne, ligneSwap);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::descendLigne(int row) {
	if(row >=0 && row < lignesWidget->rowCount()-1) {
		bool tableSwap[]={false, true, true, true, true, true, true};
		
		lignesWidget->swapRows(row, row+1, tableSwap);
		
		int curLigne=lignesWidget->item(row, cnbLigne)->text().toInt();
		int ligneSwap=lignesWidget->item(row+1, cnbLigne)->text().toInt();
		
		swapRows(curLigne, ligneSwap);
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::ligneDoubleClicked(int row, int column) {
	CComboResultFrm *comboResultFrm;
	switch(column) {
		case cnbArticle:
			comboResultFrm=new CComboResultFrm("article", "code", this);
		
			comboResultFrm->setModal(true);
			comboResultFrm->exec();
		
			if(comboResultFrm->result() == QDialog::Accepted) {
				QString requete;
				QTableWidgetItem *item=lignesWidget->item(row, column);
				double mouvement=lignesWidget->item(row, cnbQuantite)->text().toDouble();
				QString article=item->text();
				int ligne=lignesWidget->item(row, cnbLigne)->text().toInt();
				
				mouvementDeStock(article, ligne, mouvement, 0); 
				article=comboResultFrm->getResult();
				item->setText(article);
				
				requete="UPDATE ligneBLs AS lb ";
				requete+="INNER JOIN article AS a ON a.code=lb.article ";
				requete+="LEFT JOIN prixArticleClient AS pac ON pac.article=lb.article AND pac.client=\""+codeClient->getValue()+"\" ";
				requete+="SET lb.article=\""+article+"\", lb.descriptionArticle=a.nom, ";
				requete+="lb.prixUnitaireHT=IF(pac.prix IS NOT NULL, pac.prix, a.prixUnitaireHT), lb.unite=a.unite ";
				requete+="WHERE a.code=\""+article+"\" AND lb.numeroLigne="+QString::number(ligne)+" AND lb.bl="+curCode;;
				
				if(CMySQL::getInstance()->execQuery(requete)) {
					mouvementDeStock(article,ligne, 0, mouvement);
					loadGrille();
				}
			}
		
			delete comboResultFrm;
			break;
		case cnbUnite:
			comboResultFrm=new CComboResultFrm("unites", "code", this);
		
			comboResultFrm->setModal(true);
			comboResultFrm->exec();
		
			if(comboResultFrm->result() == QDialog::Accepted) {
				QTableWidgetItem *item;
		
				item=lignesWidget->item(row, column);
				
				item->setText(comboResultFrm->getResult());
			}
		
			delete comboResultFrm;
			break;
		default:
			break;
	}
}
//------------------------------------------------------------------------------
void CBLsFrm::on_cmdAdresseFacturation_clicked(bool checked) {
	CComboResultFrm *comboResultFrm=new CComboResultFrm("adressesClient", "nom", this, 0, "client = \""+codeClient->getValue()+"\"");
	
	comboResultFrm->setModal(true);
	comboResultFrm->exec();
	
	if(comboResultFrm->result() == QDialog::Accepted) {
		loadInfoAdresse(comboResultFrm->getResult().toInt(), true);
		onChange();
	}
	
	delete comboResultFrm;
}
//------------------------------------------------------------------------------
void CBLsFrm::on_cmdAdresseLivraison_clicked(bool checked) {
	CComboResultFrm *comboResultFrm=new CComboResultFrm("adressesClient", "nom", this, 0, "client = \""+codeClient->getValue()+"\"");
	
	comboResultFrm->setModal(true);
	comboResultFrm->exec();
	
	if(comboResultFrm->result() == QDialog::Accepted) {
		loadInfoAdresse(comboResultFrm->getResult().toInt(), false);
		onChange();
	}
	
	delete comboResultFrm;
}
//------------------------------------------------------------------------------
void CBLsFrm::onInvokeHelp(CChamp *champ) {
	CHelp::getInstance()->startHelp("setSource qthelp://alpes-ressources.com.coMexpert-"+VERSION_LOGICIEL+"/doc/bl.html#"+champ->getTable()+"."+champ->getChamp());
}
//------------------------------------------------------------------------------
void CBLsFrm::on_actLock_triggered(void) {
	eWidget->setVisible(actLock->isChecked());
	nomClient2->setValue(!actLock->isChecked() ? nomClient->getValue() : "");
}
//------------------------------------------------------------------------------